package com.xdemo.personal.builder;

import java.net.InetSocketAddress;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

import com.meetup.memcached.SockIOPool;
import com.xdemo.handler.MessageActionRouter;
import com.xdemo.manager.AsyncManagerImpl;
import com.xdemo.manager.DBManager;
import com.xdemo.manager.IAsyncManager;
import com.xdemo.manager.IMemcacheManager;
import com.xdemo.manager.MemcacheManager;
import com.xdemo.manager.ShortUrlDao;
import com.xdemo.model.ShortUrl;
import com.xdemo.model.VirtualUser;
import com.xdemo.personal.communityclient.CommunityServerManager;
import com.xdemo.personal.communityclient.ICommunityServerManager;
import com.xdemo.personal.config.PersonalServerConfig;
import com.xdemo.personal.handler.AsyncFinishMessageAction;
import com.xdemo.personal.handler.FileUploadAction;
import com.xdemo.personal.handler.TestMessageAction;
import com.xdemo.personal.manager.DaoManager;
import com.xdemo.personal.socketserver.PersonalSocketServerHandler;
import com.xdemo.processor.ExecutorQueueProcessor;
import com.xdemo.processor.IProcessor;
import com.xdemo.processor.QueueProcessor;

public class Builder {
	
	public static MessageActionRouter<Integer> buildMainMessageRouter() {
		MessageActionRouter<Integer> _router = new MessageActionRouter<Integer>();
		_router.registerAction(new TestMessageAction());
		_router.registerAction(new AsyncFinishMessageAction());
		//_router.registerAction(new TestExchangeAction());
		return _router;
	}
	
	public static IProcessor<Integer> buildMainProcessor(MessageActionRouter<Integer> router) {
		IProcessor<Integer> _processor = new QueueProcessor<Integer>(router);
		return _processor;
	}
	
	public static MessageActionRouter<String> buildHttpMessageRouter() {
		MessageActionRouter<String> _router = new MessageActionRouter<String>();
		_router.registerAction(new FileUploadAction());
		return _router;
	}
	
	public static IProcessor<String> buildHttpProcessor(MessageActionRouter<String> router,PersonalServerConfig serverConfig) {
		ExecutorService _executor = Executors.newFixedThreadPool(serverConfig.getHttpThreadsNum());
		IProcessor<String> _processor = new ExecutorQueueProcessor<String>(_executor,router);
		return _processor;
	}
	
	public static PersonalSocketServerHandler buildServerHandler(IProcessor<Integer> processor) {
		PersonalSocketServerHandler _handler = new PersonalSocketServerHandler(processor);
		return _handler;
	}
	
	public static IAsyncManager buildAsyncManager(IProcessor<Integer> processor,PersonalServerConfig serverConfig) {
		Executor _executor = Executors.newFixedThreadPool(serverConfig.getAsyncThreadsNum());
		IAsyncManager _manager = new AsyncManagerImpl(processor,_executor);
		return _manager;
	}
	
	public static IMemcacheManager buildMemcacheManager(PersonalServerConfig serverConfig) {
		Set<InetSocketAddress> _peers = serverConfig.getMemcachePeers();
		String[] _serverlist = new String[_peers.size()];
		int i=0;
		for(InetSocketAddress _peer : _peers) {
			_serverlist[i++] = _peer.getHostName() + ":" + _peer.getPort();
		}
		SockIOPool pool = SockIOPool.getInstance();
		pool.setServers( _serverlist );
		pool.setInitConn(5);
		pool.setMinConn(5);
		pool.setMaxConn(50);
		pool.setMaintSleep(30);
		pool.setNagle(false);
		pool.initialize();
		MemcacheManager _manager = new MemcacheManager();
		return _manager;
	}
	
	public static ICommunityServerManager buildCommunityServerManager(IProcessor<Integer> processor,PersonalServerConfig serverConfig) {
		return new CommunityServerManager(processor,serverConfig);
	}
	
	public static DBManager buildDBManager() {
		Configuration _config = new AnnotationConfiguration()
									.addAnnotatedClass(VirtualUser.class)
									.addAnnotatedClass(ShortUrl.class);
		SessionFactory _sessionFactory = _config.buildSessionFactory();
		DBManager _db = new DBManager(_sessionFactory);
		return _db;
	}
	
	public static DaoManager bulidDaoManager(DBManager dbManager) {
		DaoManager _manager = new DaoManager();
		ShortUrlDao _shortUrlDao = new ShortUrlDao(dbManager);
		_manager.setShortUrlDao(_shortUrlDao);
		return _manager;
	}
}
